From 8bb0d552f1be1313cbb9e37607b21d8274ae5ff1 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 28 Jan 2011 19:36:24 -0500 Subject: [PATCH] Improve binding-set parser Make gtk_binding_entry_add_signal_from_string() return the expected token in case of parsing error, so that we can return a GError instead of spewing. Also, add a separate scope for binding-set, since allowing {} in identifiers in SCOPE_VALUE breaks the fact that the ; after the last assignment in a rule is optional. --- gtk/gtkbindings.c | 19 ++++++++++--------- gtk/gtkbindings.h | 4 ++-- gtk/gtkcssprovider.c | 23 +++++++++++++++++++---- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c index 2b9d51230f..ef31fb9746 100644 --- a/gtk/gtkbindings.c +++ b/gtk/gtkbindings.c @@ -1271,17 +1271,20 @@ create_signal_scanner (void) * Key combinations must be in a format that can be parsed by * gtk_accelerator_parse(). * + * Returns: %G_TOKEN_NONE if the signal was successfully parsed and added, + * the expected token otherwise + * * Since: 3.0 - **/ -void + */ +GTokenType gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set, - const gchar *signal_desc) + const gchar *signal_desc) { static GScanner *scanner = NULL; GTokenType ret; - g_return_if_fail (binding_set != NULL); - g_return_if_fail (signal_desc != NULL); + g_return_val_if_fail (binding_set != NULL, G_TOKEN_NONE); + g_return_val_if_fail (signal_desc != NULL, G_TOKEN_NONE); if (G_UNLIKELY (!scanner)) scanner = create_signal_scanner (); @@ -1291,12 +1294,10 @@ gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set, ret = gtk_binding_parse_bind (scanner, binding_set); - if (ret != G_TOKEN_NONE) - g_scanner_unexp_token (scanner, ret, NULL, NULL, NULL, - "Could not parse binding", FALSE); - /* Reset for next use */ g_scanner_set_scope (scanner, 0); + + return ret; } /** diff --git a/gtk/gtkbindings.h b/gtk/gtkbindings.h index 4529567a6c..cf7f6bfb14 100644 --- a/gtk/gtkbindings.h +++ b/gtk/gtkbindings.h @@ -125,8 +125,8 @@ void gtk_binding_entry_add_signall (GtkBindingSet *binding_set, const gchar *signal_name, GSList *binding_args); -void gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set, - const gchar *signal_desc); +GTokenType gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set, + const gchar *signal_desc); void gtk_binding_entry_remove (GtkBindingSet *binding_set, guint keyval, diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c index a0992f740a..b43d52f7cd 100644 --- a/gtk/gtkcssprovider.c +++ b/gtk/gtkcssprovider.c @@ -801,7 +801,8 @@ enum ParserScope { SCOPE_PSEUDO_CLASS, SCOPE_NTH_CHILD, SCOPE_DECLARATION, - SCOPE_VALUE + SCOPE_VALUE, + SCOPE_BINDING_SET }; /* Extend GtkStateType, since these @@ -1505,6 +1506,12 @@ scanner_apply_scope (GScanner *scanner, g_scanner_set_scope (scanner, scope); if (scope == SCOPE_VALUE) + { + scanner->config->cset_identifier_first = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_"; + scanner->config->cset_identifier_nth = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_ +(),.%\t\n'/\""; + scanner->config->scan_identifier_1char = TRUE; + } + else if (scope == SCOPE_BINDING_SET) { scanner->config->cset_identifier_first = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_"; scanner->config->cset_identifier_nth = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_ +(){}<>,.%\t\n'/\""; @@ -3318,19 +3325,27 @@ parse_rule (GtkCssProvider *css_provider, if (scanner->token != G_TOKEN_LEFT_CURLY) return G_TOKEN_LEFT_CURLY; - css_provider_push_scope (css_provider, SCOPE_VALUE); + css_provider_push_scope (css_provider, SCOPE_BINDING_SET); g_scanner_get_next_token (scanner); do { + GTokenType ret; + if (scanner->token != G_TOKEN_IDENTIFIER) { scanner->user_data = "Binding definition"; return G_TOKEN_IDENTIFIER; } - gtk_binding_entry_add_signal_from_string (binding_set, - scanner->value.v_identifier); + ret = gtk_binding_entry_add_signal_from_string (binding_set, + scanner->value.v_identifier); + if (ret != G_TOKEN_NONE) + { + scanner->user_data = "Binding definition"; + return ret; + } + g_scanner_get_next_token (scanner); if (scanner->token != ';') -- 2.30.2